package cn.csg.iotplatform.module.system.dal.mysql.user;

import cn.csg.iotplatform.framework.common.pojo.PageResult;
import cn.csg.iotplatform.framework.mybatis.core.mapper.BaseMapperX;
import cn.csg.iotplatform.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csg.iotplatform.module.system.api.user.dto.AdminUserDeptRespDTO;
import cn.csg.iotplatform.module.system.controller.admin.permission.vo.permission.RoleUserListReqDto;
import cn.csg.iotplatform.module.system.controller.admin.user.vo.user.UserPageReqVO;
import cn.csg.iotplatform.module.system.controller.admin.user.vo.user.UserStatDetailRespVO;
import cn.csg.iotplatform.module.system.controller.admin.user.vo.user.UserStatRespVO;
import cn.csg.iotplatform.module.system.dal.dataobject.user.AdminUserDO;
import cn.csg.iotplatform.module.system.enums.ErrorCodeConstants;
import cn.csg.iotplatform.module.system.util.ToolUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;

import static cn.csg.iotplatform.framework.common.exception.util.ServiceExceptionUtil.exception;

@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {

    default AdminUserDO selectByUsername(String username) {
        //return selectOne(new LambdaQueryWrapperX<AdminUserDO>().eq(AdminUserDO::getUsername, username).eq(AdminUserDO::getDeleted, 0));
//        if (selectCount(AdminUserDO::getUsername, username) > 1) { //临时拦截异常信息,待数据完善后可注释该浪费性能的逻辑     -- by Mr.Z  24.03.13
//            throw exception(ErrorCodeConstants.USER_ERROR, "username");
//        }
        List<AdminUserDO> adminUserDOS = selectList(AdminUserDO::getUsername, username);
        return ToolUtil.isNotEmpty(adminUserDOS) ? adminUserDOS.get(0) : null;
    }

    default AdminUserDO selectByEmail(String email) {
        //return selectOne(new LambdaQueryWrapperX<AdminUserDO>().eq(AdminUserDO::getEmail, email).eq(AdminUserDO::getDeleted, 0));
//        if (selectCount(AdminUserDO::getEmail, email) > 1) { //临时拦截异常信息,待数据完善后可注释该浪费性能的逻辑       -- by Mr.Z  24.03.13
//            throw exception(ErrorCodeConstants.USER_ERROR, "email");
//        }
        List<AdminUserDO> adminUserDOS = selectList(AdminUserDO::getEmail, email);
        return ToolUtil.isNotEmpty(adminUserDOS) ? adminUserDOS.get(0) : null;
    }

    default AdminUserDO selectByMobile(String mobile) {
        //return selectOne(new LambdaQueryWrapperX<AdminUserDO>().eq(AdminUserDO::getMobile, mobile).eq(AdminUserDO::getDeleted, 0));
//        if (selectCount(AdminUserDO::getMobile, mobile) > 1) { //临时拦截异常信息,待数据完善后可注释该浪费性能的逻辑     -- by Mr.Z  24.03.13
//            throw exception(ErrorCodeConstants.USER_ERROR, "mobile");
//        }
        List<AdminUserDO> adminUserDOS = selectList(AdminUserDO::getMobile, mobile);
        return ToolUtil.isNotEmpty(adminUserDOS) ? adminUserDOS.get(0) : null;
    }

    default AdminUserDO selectByUserNo(String userNo) {
//        if (selectCount(AdminUserDO::getUserNo, userNo) > 1) { //临时拦截异常信息,待数据完善后可注释该浪费性能的逻辑     -- by Mr.Z  24.03.15
//            throw exception(ErrorCodeConstants.USER_ERROR, "userNo");
//        }
        List<AdminUserDO> adminUserDOS = selectList(AdminUserDO::getUserNo, userNo);
        return ToolUtil.isNotEmpty(adminUserDOS) ? adminUserDOS.get(0) : null;
    }

    default PageResult<AdminUserDO> selectPage(UserPageReqVO reqVO, Collection<Long> deptIds) {
        return selectPage(reqVO, new LambdaQueryWrapperX<AdminUserDO>()
                .eq(AdminUserDO::getDeleted, 0)
                .eqIfPresent(AdminUserDO::getIsValid, reqVO.getIsValid())
                .likeIfPresent(AdminUserDO::getNickname, reqVO.getNickname())
                .likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername())
                .likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile())
                .eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(AdminUserDO::getCreateTime, reqVO.getCreateTime())
                .inIfPresent(AdminUserDO::getDeptId, deptIds)
                .inIfPresent(AdminUserDO::getId, reqVO.getIds())
                .ne(AdminUserDO::getId, 1L)
                .orderByDesc(AdminUserDO::getId));
    }

    default List<AdminUserDO> selectListByNickname(String nickname) {
        return selectList(new LambdaQueryWrapperX<AdminUserDO>().like(AdminUserDO::getNickname, nickname));
    }

    default List<AdminUserDO> selectListByStatus(Integer status) {
        return selectList(AdminUserDO::getStatus, status);
    }

    default List<AdminUserDO> selectListByDeptIds(Collection<Long> deptIds) {
        return selectList(AdminUserDO::getDeptId, deptIds);
    }


    default List<AdminUserDO> selectByUserIds(List<Long> userIds) {
        return selectList(new LambdaQueryWrapperX<AdminUserDO>()
                .inIfPresent(AdminUserDO::getId, userIds));
    }

    default List<AdminUserDO> getRoleUserListByRoleId(RoleUserListReqDto dto) {
        return selectList(new LambdaQueryWrapperX<AdminUserDO>()
                .inIfPresent(AdminUserDO::getId, dto.getUserIds())
                .likeIfPresent(AdminUserDO::getNickname, dto.getNickname())
                .likeIfPresent(AdminUserDO::getUsername, dto.getUsername())
        );
    }

    UserStatRespVO getUserStat(@Param("reqVO") UserPageReqVO reqVO);

    IPage<UserStatDetailRespVO> getUserStatDetail(IPage<UserStatDetailRespVO> page,@Param("reqVO") UserPageReqVO reqVO);

    /*
     * 物理删除所有用户
     */
    void deleteAll();

    AdminUserDO getUserData(Long id);

    List<AdminUserDO> getUserListByUserName(@Param("userNames") List<String> userNames);

    /*
     * 获得用户列表，基于昵称模糊匹配--查询出所有用户（包括物理删除的用户）
     */
    List<AdminUserDO> selectAllUserListByNickname(@Param("nickname") String nickname);

    /*
     * 获得用户列表，基于id--查询出所有用户（包括物理删除的用户）
     */
    List<AdminUserDO> getAllUserListByIds(@Param("Ids") Collection<Long> Ids);

    List<AdminUserDeptRespDTO> getUserDeptList(@Param("ids")Collection<Long> ids);

    String getPasswordValidDay(@Param("configKey") String configKey);
}
